using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using limpalex.bbparser.Tokens;

namespace limpalex.bbparser.Tree
{
    sealed class Branch : INode, IEnumerable<INode>
    {
        private TagToken _tagToken;
        private readonly List<INode> _nodes = new List<INode>();
        private Branch _parent;

        public int NodesCount
        {
            get { return _nodes.Count; }
        }

        public Tag Tag { get; set; }

        public void GetText(StringBuilder buffer, Parser parser)
        {
            var length = buffer.Length;
            foreach (var node in _nodes)
            {
                node.GetText(buffer, parser);
            }

            var data = new char[buffer.Length - length];
            buffer.CopyTo(length, data, 0, data.Length);
            buffer.Remove(length, data.Length);

            var content = new string(data);
            if ( Tag.UseSmileys )
            {
                content = parser.SmileyConfiguration.ProcessText(content);
            }
            var parameters = new TagParameterList {ContentParameter = content};

            if (!string.IsNullOrEmpty(_tagToken.DefaultValue))
                parameters.DefaultParameter = _tagToken.DefaultValue;
            parameters.AddFromList(_tagToken.Attributes);

            buffer.Append(_tagToken.Replacement.Process(parameters));
        }

        public NodeType Type
        {
            get { return NodeType.Branch; }
        }

        internal TagToken TagToken
        {
            get { return _tagToken; }
            set { _tagToken = value; }
        }

        public Branch Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }

        public void AddNode(INode node)
        {
            _nodes.Add(node);
        }

        public void RemoveNode(INode node)
        {
            _nodes.Remove(node);
        }

        public IEnumerator<INode> GetEnumerator()
        {
            return _nodes.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}